
  $ . ./setup.sh
  $ cat > dune-project <<EOF
  > (lang dune 3.8)
  > (using melange 0.1)
  > EOF
  $ cat > dune <<EOF
  > (melange.emit
  >  (target js-out)
  >  (emit_stdlib false)
  >  (libraries melange.js)
  >  (preprocess (pps melange.ppx)))
  > EOF
  $ cat > x.ml << EOF
  > exception A of int
  > let () =
  >   let a0 =
  >     try [%mel.raw{| (function (){throw 2} ()) |}] with
  >     | A x -> x
  >     | Js.Exn.Error v -> Obj.magic v
  >     | _ -> assert false
  >   in
  >   Js.log a0
  > EOF
  $ dune build @melange
  $ cat _build/default/js-out/x.js
  // Generated by Melange
  'use strict';
  
  const Caml_exceptions = require("melange.js/caml_exceptions.js");
  const Caml_js_exceptions = require("melange.js/caml_js_exceptions.js");
  const Js__Js_exn = require("melange.js/js_exn.js");
  
  const A = /* @__PURE__ */ Caml_exceptions.create("Melange__X.A");
  
  let a0;
  
  try {
    a0 = ((function (){throw 2} ())
    );
  }
  catch (raw_x){
    const x = Caml_js_exceptions.internalToOCamlException(raw_x);
    if (x.MEL_EXN_ID === A || x.MEL_EXN_ID === Js__Js_exn.$$Error) {
      a0 = x._1;
    } else {
      throw new Caml_js_exceptions.MelangeError("Assert_failure", {
          MEL_EXN_ID: "Assert_failure",
          _1: [
            "x.ml",
            7,
            11
          ]
        });
    }
  }
  
  console.log(a0);
  
  module.exports = {
    A,
  }
  /* a0 Not a pure module */
  $ node _build/default/js-out/x.js
  2

Raise `null` / `undefined`

  $ cat > x.ml << EOF
  > exception A of int
  > let () =
  >   let a0 =
  >     try [%mel.raw{| (function (){throw undefined} ()) |}] with
  >     | A x -> x
  >     | Js.Exn.Error v -> Obj.magic v
  >     | _ -> assert false
  >   and a1 =
  >     try [%mel.raw{| (function (){throw null} ()) |}] with
  >     | A x -> x
  >     | Js.Exn.Error v -> Obj.magic v
  >     | _ -> assert false
  >   in
  >   Js.log2 a0 a1
  > EOF
  $ dune build @melange
  $ cat _build/default/js-out/x.js
  // Generated by Melange
  'use strict';
  
  const Caml_exceptions = require("melange.js/caml_exceptions.js");
  const Caml_js_exceptions = require("melange.js/caml_js_exceptions.js");
  const Js__Js_exn = require("melange.js/js_exn.js");
  
  const A = /* @__PURE__ */ Caml_exceptions.create("Melange__X.A");
  
  let a0;
  
  try {
    a0 = ((function (){throw undefined} ())
    );
  }
  catch (raw_x){
    const x = Caml_js_exceptions.internalToOCamlException(raw_x);
    if (x.MEL_EXN_ID === A || x.MEL_EXN_ID === Js__Js_exn.$$Error) {
      a0 = x._1;
    } else {
      throw new Caml_js_exceptions.MelangeError("Assert_failure", {
          MEL_EXN_ID: "Assert_failure",
          _1: [
            "x.ml",
            7,
            11
          ]
        });
    }
  }
  
  let a1;
  
  try {
    a1 = ((function (){throw null} ())
    );
  }
  catch (raw_x$1){
    const x$1 = Caml_js_exceptions.internalToOCamlException(raw_x$1);
    if (x$1.MEL_EXN_ID === A || x$1.MEL_EXN_ID === Js__Js_exn.$$Error) {
      a1 = x$1._1;
    } else {
      throw new Caml_js_exceptions.MelangeError("Assert_failure", {
          MEL_EXN_ID: "Assert_failure",
          _1: [
            "x.ml",
            12,
            11
          ]
        });
    }
  }
  
  console.log(a0, a1);
  
  module.exports = {
    A,
  }
  /* a0 Not a pure module */
  $ node _build/default/js-out/x.js
  undefined null

  $ cat > x.ml << EOF
  > exception A of int
  > let () =
  >   let a0 =
  >     try raise (A 42) with
  >     | A x -> x
  >     | _ -> assert false
  >   in
  >   Js.log a0
  > EOF
  $ dune build @melange
  $ cat _build/default/js-out/x.js
  // Generated by Melange
  'use strict';
  
  const Caml_exceptions = require("melange.js/caml_exceptions.js");
  const Caml_js_exceptions = require("melange.js/caml_js_exceptions.js");
  
  const A = /* @__PURE__ */ Caml_exceptions.create("Melange__X.A");
  
  let a0;
  
  try {
    throw new Caml_js_exceptions.MelangeError(A, {
        MEL_EXN_ID: A,
        _1: 42
      });
  }
  catch (raw_x){
    const x = Caml_js_exceptions.internalToOCamlException(raw_x);
    if (x.MEL_EXN_ID === A) {
      a0 = x._1;
    } else {
      throw new Caml_js_exceptions.MelangeError("Assert_failure", {
          MEL_EXN_ID: "Assert_failure",
          _1: [
            "x.ml",
            6,
            11
          ]
        });
    }
  }
  
  console.log(a0);
  
  module.exports = {
    A,
  }
  /* a0 Not a pure module */

  $ node _build/default/js-out/x.js
  42

Re-throw

  $ cat > x.ml << EOF
  > exception A of int
  > let () =
  >   let a0 =
  >     try raise (A 42) with
  >     | (A _) as e -> raise e
  >     | _ -> assert false
  >   in
  >   Js.log a0
  > EOF
  $ dune build @melange
  $ cat _build/default/js-out/x.js
  // Generated by Melange
  'use strict';
  
  const Caml_exceptions = require("melange.js/caml_exceptions.js");
  const Caml_js_exceptions = require("melange.js/caml_js_exceptions.js");
  
  const A = /* @__PURE__ */ Caml_exceptions.create("Melange__X.A");
  
  let a0;
  
  try {
    throw new Caml_js_exceptions.MelangeError(A, {
        MEL_EXN_ID: A,
        _1: 42
      });
  }
  catch (raw_e){
    const e = Caml_js_exceptions.internalToOCamlException(raw_e);
    if (e.MEL_EXN_ID === A) {
      throw e;
    }
    throw new Caml_js_exceptions.MelangeError("Assert_failure", {
        MEL_EXN_ID: "Assert_failure",
        _1: [
          "x.ml",
          6,
          11
        ]
      });
  }
  
  console.log(a0);
  
  module.exports = {
    A,
  }
  /* a0 Not a pure module */
  $ node _build/default/js-out/x.js 2>&1 | grep -v Node | grep -vE '\s+at'
  $TESTCASE_ROOT/_build/default/js-out/x.js:20
      throw e;
      ^
  
  Error [MelangeError]: Melange__X.A/1
    MEL_EXN_ID: 'Melange__X.A/1',
    _1: 42,
    [cause]: { MEL_EXN_ID: 'Melange__X.A/1', _1: 42 }
  }
  


Exception without raising

  $ cat > x.ml << EOF
  > exception A of int
  > let _a = A 42
  > EOF
  $ dune build @melange
  $ cat _build/default/js-out/x.js
  // Generated by Melange
  'use strict';
  
  const Caml_exceptions = require("melange.js/caml_exceptions.js");
  const Caml_js_exceptions = require("melange.js/caml_js_exceptions.js");
  
  const A = /* @__PURE__ */ Caml_exceptions.create("Melange__X.A");
  
  const _a = new Caml_js_exceptions.MelangeError(A, {
      MEL_EXN_ID: A,
      _1: 42
    });
  
  module.exports = {
    A,
    _a,
  }
  /* No side effect */

